/*  File Name	: Configurator.cpp
 *  Author		: Pang Jiacai
 *	 E-mail		: 823960168@qq.com
 *  Created on	: 2012-6-30
 *  Description:
 */

#include "Configurator.h"
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include "Logger.h"

Configurator *Configurator::instance_= NULL;

Configurator::Configurator()
{
	this->has_load_cfg_ = false;
	this->service_.clear() ;//= Json::Value::null;
	this->daemon_.clear();// = Json::Value::null;
	this->engine_.clear();// = Json::Value::null;
	this->dircserver_.clear();
	this->gateway_.clear();// = Json::Value::null;
	this->chat_.clear();// = Json::Value::null;
	this->dbserver_.clear();// = Json::Value::null;
	this->sandbox_.clear();//= Json::Value::null;
}

Configurator::~Configurator()
{
	this->has_load_cfg_ = false;
}

Configurator *Configurator::instance(void)
{
	if(NULL==instance_)
	{
		instance_ = new Configurator();
	}
	return instance_;
}


int Configurator::load_json_file(const char *file,Json::Value &cfg)
{
    FILE *fd = fopen(file, "rb");

    if (fd == 0)
    {
        return -1;
    }

    fseek(fd, 0, SEEK_END);
    long size = ftell(fd);
    fseek(fd, 0, SEEK_SET);

    std::string config_doc = "";

    MessageBlock mb(size + 1);

    if (fread(mb.wr_ptr(), 1, size, fd) == (unsigned long) size)
    {
        config_doc = mb.rd_ptr();
    }
    fclose(fd);

    if (this->json_reader_.parse(config_doc, cfg) == false)
    {
        char error[4096]={0};
        sprintf(error,"Failed to parse file %s\n error: %s\n context: %s.\n",file,
        		this->json_reader_.getFormatedErrorMessages().c_str(),config_doc.c_str());
        std::cout << error <<std::endl;
        LOG((ERROR_LOG,error));
        return -1;
    }
	return 0;
}


void Configurator::load_config(void)
{
	if(this->has_load_cfg_==false)
	{
		LockGuardReturn(RT_MUTEX,lock,this->rt_mutex,;);
		this->has_load_cfg_ = true;
	}
	else
	{
		return ;
	}
	this->load_daemon();
	this->load_chat();
	this->load_dbserver();
	this->load_engine();
	this->load_dircserver();
	this->load_gateway();
	this->load_sandbox();
	this->load_sql_cfg();
}

int Configurator::load_daemon(void)
{
	std::string cfg_file("ConfigFile/daemon.json");

	LockGuardReturn(RT_MUTEX,lock,this->rt_mutex,-1);
	this->daemon_.clear();
	if(this->load_json_file(cfg_file.c_str(),this->daemon_)==0)
	{
		return 0;
	}
	this->daemon_ = Json::Value::null;
	return -1;
}

int Configurator::load_gateway(void)
{
	std::string cfg_file("ConfigFile/gateway.json");

	LockGuardReturn(RT_MUTEX,lock,this->rt_mutex,-1);
	this->gateway_.clear();
	if(this->load_json_file(cfg_file.c_str(),this->gateway_)==0)
	{
		return 0;
	}
	this->gateway_ = Json::Value::null;
	return -1;
}

int Configurator::load_engine(void)
{
	std::string cfg_file("ConfigFile/engine.json");

	LockGuardReturn(RT_MUTEX,lock,this->rt_mutex,-1);
	this->engine_.clear();
	if(this->load_json_file(cfg_file.c_str(),this->engine_)==0)
	{
		return 0;
	}
	this->engine_ = Json::Value::null;
	return -1;
}

int Configurator::load_dircserver(void)
{
	std::string cfg_file("ConfigFile/dircserver.json");

	LockGuardReturn(RT_MUTEX,lock,this->rt_mutex,-1);
	this->dircserver_.clear();
	if(this->load_json_file(cfg_file.c_str(),this->dircserver_)==0)
	{
		return 0;
	}
	this->dircserver_ = Json::Value::null;
	return -1;
}

int Configurator::load_dbserver(void)
{
	std::string cfg_file("ConfigFile/dbserver.json");

	LockGuardReturn(RT_MUTEX,lock,this->rt_mutex,-1);
	this->dbserver_.clear();
	if(this->load_json_file(cfg_file.c_str(),this->dbserver_)==0)
	{
		return 0;
	}
	this->dbserver_ = Json::Value::null;
	return -1;
}

int Configurator::load_chat(void)
{
	std::string cfg_file("ConfigFile/chat.json");

	LockGuardReturn(RT_MUTEX,lock,this->rt_mutex,-1);
	this->chat_.clear();
	if(this->load_json_file(cfg_file.c_str(),this->chat_)==0)
	{
		return 0;
	}
	this->chat_ = Json::Value::null;
	return -1;
}

int Configurator::load_sandbox(void)
{
	std::string cfg_file("ConfigFile/sandbox.json");

	LockGuardReturn(RT_MUTEX,lock,this->rt_mutex,-1);
	this->sandbox_.clear();
	if(this->load_json_file(cfg_file.c_str(),this->sandbox_)==0)
	{
		return 0;
	}
	this->sandbox_ = Json::Value::null;
	return -1;
}

int Configurator::load_sql_cfg(void)
{
	std::string cfg_file("ConfigFile/sql.json");

	LockGuardReturn(RT_MUTEX,lock,this->rt_mutex,-1);
	this->sql_.clear();
	if(this->load_json_file(cfg_file.c_str(),this->sql_)==0)
	{
		return 0;
	}
	this->sql_ = Json::Value::null;
	return -1;
}

//////////////////////////////////////////////////////////////

//const Json::Value &Configurator::serivce_cfg(void)
//{
//	LockGuardReturn(RT_MUTEX,lock,this->rt_mutex,Json::Value::null);
//	return this->service_;
//}

const Json::Value &Configurator::daemon(void)
{
	LockGuardReturn(RT_MUTEX,lock,this->rt_mutex,Json::Value::null);
	return this->daemon_;
}

const Json::Value &Configurator::engine(void)
{
	LockGuardReturn(RT_MUTEX,lock,this->rt_mutex,Json::Value::null);
	return this->engine_;
}

const Json::Value &Configurator::gateway(void)
{
	LockGuardReturn(RT_MUTEX,lock,this->rt_mutex,Json::Value::null);
	return this->gateway_;
}

const Json::Value &Configurator::dircserver(void)
{
	LockGuardReturn(RT_MUTEX,lock,this->rt_mutex,Json::Value::null);
	return this->dircserver_;
}

const Json::Value &Configurator::dbserver(void)
{
	LockGuardReturn(RT_MUTEX,lock,this->rt_mutex,Json::Value::null);
	return this->dbserver_;
}

const Json::Value &Configurator::chat(void)
{
	LockGuardReturn(RT_MUTEX,lock,this->rt_mutex,Json::Value::null);
	return this->chat_;
}

const Json::Value &Configurator::sandbox(void)
{
	LockGuardReturn(RT_MUTEX,lock,this->rt_mutex,Json::Value::null);
	return this->sandbox_;
}

const Json::Value &Configurator::sql_cfg(void)
{
	LockGuardReturn(RT_MUTEX,lock,this->rt_mutex,Json::Value::null);
	return this->sql_;
}
